package com.chenbei.controller.admin.system;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chenbei.common.annotation.OperationLog;
import com.chenbei.common.constants.CacheKeys;
import com.chenbei.common.enums.ResponseResultEnum;
import com.chenbei.common.service.IEmailService;
import com.chenbei.common.util.PaginationUtil;
import com.chenbei.common.util.ApiResponseUtil;
import com.chenbei.common.util.ValidatorUtil;
import com.chenbei.common.domain.vo.Pagination;
import com.chenbei.common.domain.vo.ApiResponse;
import com.chenbei.common.domain.vo.UploadFileResult;
import com.chenbei.system.domain.SysOrganization;
import com.chenbei.system.domain.SysUser;
import com.chenbei.system.service.ISysRoleService;
import com.chenbei.system.service.ISysUserRoleService;
import com.chenbei.system.service.ISysUserService;
import com.chenbei.system.service.impl.SysOrganizationService;
import com.chenbei.system.service.impl.SysUserService;
import com.chenbei.system.util.SysUserSelectorDataRespUtil;
import com.chenbei.system.vo.AdminUserEmailBind;
import com.chenbei.system.vo.AdminUserPasswordModify;
import com.chenbei.system.vo.AdminUserPhoneBind;
import com.chenbei.system.vo.req.SysUserBindRolesReq;
import com.chenbei.system.vo.req.SysUserReq;
import com.chenbei.system.vo.req.SysUserSelectorReq;
import com.chenbei.system.vo.resp.AdminUserMenuResp;
import com.chenbei.system.vo.resp.SysUserSelectorDataResp;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Tag(name = "管理员管理")
@RestController
@RequestMapping("/admin/system/adminUser")
public class SysUserController {

    @Autowired
    public ISysUserService adminUserService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private IEmailService qqEmailService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private ISysUserRoleService sysUserRoleService;

    @SaCheckPermission(value = "system:sys_user:add", orRole = "root")
    @Operation(summary = "管理员添加")
    @PostMapping("add")
    @OperationLog(moduleName = "管理员管理", eventName = "添加管理员")
    public ApiResponse<Object> add(@RequestBody SysUser sysUser) {
        adminUserService.add(sysUser);
        return ApiResponseUtil.success();
    }

    @SaCheckPermission(value = "system:sys_user:list", orRole = "root")
    @Operation(summary = "管理员列表")
    @GetMapping("pageList")
    @OperationLog(moduleName = "管理员管理", eventName = "获取管理员列表")
    public ApiResponse<Pagination<SysUser>> pageList(SysUserReq sysUserReq) {
        IPage<SysUser> page = adminUserService.page(sysUserReq);
        return ApiResponseUtil.success(PaginationUtil.toPagination(page));
    }

    @Operation(summary = "下拉选项列表集合")
    @GetMapping("selectList")
    public ApiResponse<List<SysUser>> selectList() {
        SysUserReq sysUserReq = new SysUserReq();
        sysUserReq.setStatus(1);
        List<SysUser> list = sysUserService.list(sysUserReq);
        return ApiResponseUtil.success(list);
    }

    @Operation(summary = "用户选择器下拉菜单数据集合")
    @GetMapping("listSysUserSelectorData")
    public ApiResponse<List<SysUserSelectorDataResp>> listSysUserSelectorData(SysUserSelectorReq sysUserSelectorReq) {
        List<SysUserSelectorDataResp> selectorDataRespList = new ArrayList<>();

        if (StrUtil.isNotBlank(sysUserSelectorReq.getName())) {
            SysUserReq sysUserReq = new SysUserReq();
            sysUserReq.setNickname(sysUserSelectorReq.getName());
            List<SysUser> sysUsers = sysUserService.list(sysUserReq);
            selectorDataRespList.addAll(SysUserSelectorDataRespUtil.convertSysUsers(sysUsers));
        } else {
            selectorDataRespList = sysUserService.listSysUserSelectorData(sysUserSelectorReq.getOrgId());

        }
        return ApiResponseUtil.success(selectorDataRespList);
    }

    @Operation(summary = "列表")
    @PostMapping("list")
    public ApiResponse<List<SysUser>> list(@RequestBody SysUserReq sysUserReq) {
        List<SysUser> list = sysUserService.list(sysUserReq);
        return ApiResponseUtil.success(list);
    }

    @SaCheckPermission(value = "system:sys_user:update", orRole = "root")
    @PostMapping("update")
    @Operation(summary = "管理员更新")
    @OperationLog(moduleName = "管理员管理", eventName = "更新管理员")
    public ApiResponse<Object> update(@RequestBody SysUser sysUser) {
        adminUserService.update(sysUser);
        return ApiResponseUtil.success();
    }

    @SaCheckPermission(value = "system:sys_user:delete", orRole = "root")
    @PostMapping("deleteById/{id}")
    @OperationLog(moduleName = "管理员管理", eventName = "删除管理员")
    @Operation(summary = "管理员删除")
    public ApiResponse<Object> delete(@PathVariable Long id) {
        adminUserService.delete(id);

        return ApiResponseUtil.success();
    }

    @SaCheckPermission(value = "system:sys_user:detail", orRole = "root")
    @Operation(summary = "系统用户详情")
    @GetMapping("detail")
    public ApiResponse<SysUser> detail(@RequestParam(name = "id", required = false) Long id) {
        if (id == null) {
            id = StpUtil.getLoginIdAsLong();
        }
        return ApiResponseUtil.success(adminUserService.detail(id));
    }

    @Operation(summary = "发送绑定邮箱验证码")
    @GetMapping("sendBindEmailCode")
    @OperationLog(moduleName = "管理员管理", eventName = "发送绑定邮箱验证码")
    public ApiResponse<Object> sendBindEmailCode(@RequestParam String email) {
        if (!ValidatorUtil.validateEmail(email)) {
            return ApiResponseUtil.fail(ResponseResultEnum.REQUEST_PARAM_VERIFY_FAILED, "邮箱格式不正确");
        }
        String randomCode = RandomUtil.randomNumbers(4);
        stringRedisTemplate.opsForValue().set(CacheKeys.VERIFICATION_CODE_CACHE_KEY + email, randomCode, 5, TimeUnit.MINUTES);
        qqEmailService.sendText(email, "邮箱绑定", "你正在进行邮箱绑定操作，验证码：" + randomCode + "，5分钟有效。请尽快完成绑定操作。");
        return ApiResponseUtil.success();
    }

    @Operation(summary = "绑定邮箱")
    @PostMapping("bindEmail")
    @OperationLog(moduleName = "管理员管理", eventName = "绑定邮箱")
    public ApiResponse<Object> bindEmail(@RequestBody AdminUserEmailBind adminUserEmailBind) {
        String cacheCode = stringRedisTemplate.opsForValue().get(CacheKeys.VERIFICATION_CODE_CACHE_KEY + adminUserEmailBind.getEmail());
        if (StringUtils.isBlank(cacheCode) || !cacheCode.equals(adminUserEmailBind.getCode())) {
            return ApiResponseUtil.fail(ResponseResultEnum.REQUEST_PARAM_VERIFY_FAILED, "无效的验证码");
        }
        adminUserService.bindEmail(StpUtil.getLoginIdAsLong(), adminUserEmailBind.getEmail());
        stringRedisTemplate.delete(CacheKeys.VERIFICATION_CODE_CACHE_KEY + adminUserEmailBind.getEmail());
        return ApiResponseUtil.success();
    }

    @Operation(summary = "发送绑定手机号验证码")
    @GetMapping("sendBindPhoneCode")
    @OperationLog(moduleName = "管理员管理", eventName = "发送绑定手机号验证码")
    public ApiResponse<Object> sendBindPhoneCode(@RequestParam String phone) {
        if (!ValidatorUtil.validatePhone(phone)) {
            return ApiResponseUtil.fail(ResponseResultEnum.REQUEST_PARAM_VERIFY_FAILED, "手机号格式不正确");
        }
        String randomCode = RandomUtil.randomNumbers(4);
        stringRedisTemplate.opsForValue().set(CacheKeys.VERIFICATION_CODE_CACHE_KEY + phone, randomCode, 5, TimeUnit.MINUTES);
        //发送短信CODE
        return ApiResponseUtil.success();
    }

    @Operation(summary = "绑定手机号")
    @PostMapping("bindPhone")
    @OperationLog(moduleName = "管理员管理", eventName = "绑定手机号")
    public ApiResponse<Object> bindPhone(@RequestBody AdminUserPhoneBind adminUserPhoneBind) {
        String cacheCode = stringRedisTemplate.opsForValue().get(CacheKeys.VERIFICATION_CODE_CACHE_KEY + adminUserPhoneBind.getPhone());
        if (StringUtils.isBlank(cacheCode) || !cacheCode.equals(adminUserPhoneBind.getCode())) {
            return ApiResponseUtil.fail(ResponseResultEnum.REQUEST_PARAM_VERIFY_FAILED, "无效的验证码");
        }
        adminUserService.bindPhone(StpUtil.getLoginIdAsLong(), adminUserPhoneBind.getPhone());
        stringRedisTemplate.delete(CacheKeys.VERIFICATION_CODE_CACHE_KEY + adminUserPhoneBind.getPhone());
        return ApiResponseUtil.success();
    }

    @Operation(summary = "密码修改")
    @PostMapping("modifyPassword")
    @OperationLog(moduleName = "管理员管理", eventName = "密码修改")
    public ApiResponse<Object> modifyPassword(@RequestBody AdminUserPasswordModify adminUserPasswordModify) {
        if (!adminUserPasswordModify.getNewPassword().equals(adminUserPasswordModify.getConfirmPassword())) {
            return ApiResponseUtil.fail(ResponseResultEnum.REQUEST_PARAM_VERIFY_FAILED, "新密码和确认密码不一致");
        }
        if (adminUserPasswordModify.getNewPassword().equals(adminUserPasswordModify.getOldPassword())) {
            return ApiResponseUtil.fail(ResponseResultEnum.REQUEST_PARAM_VERIFY_FAILED, "新密码和旧密码一致");
        }
        adminUserService.modifyPassword(StpUtil.getLoginIdAsLong(), adminUserPasswordModify.getOldPassword(), adminUserPasswordModify.getNewPassword());
        return ApiResponseUtil.success();
    }

    @Operation(summary = "重置密码")
    @GetMapping("resetPassword")
    @OperationLog(moduleName = "管理员管理", eventName = "重置密码")
    public ApiResponse<Object> resetPassword(@RequestParam Long id) {
        adminUserService.resetPassword(id);
        return ApiResponseUtil.success();
    }

    @Operation(summary = "上传头像")
    @OperationLog(moduleName = "管理员管理", eventName = "上传头像")
    @PostMapping("uploadAvatar")
    public ApiResponse<UploadFileResult> uploadAvatar(@RequestParam("file") MultipartFile file) {
        return ApiResponseUtil.success(adminUserService.uploadAvatar(file));
    }

    @Operation(summary = "绑定角色")
    @OperationLog(moduleName = "管理员管理", eventName = "授权角色")
    @PostMapping("bindRoles")
    public ApiResponse<Boolean> bindRoles(@RequestBody SysUserBindRolesReq sysUserBindRolesReq) {
        sysUserRoleService.userBindRoles(sysUserBindRolesReq.getUserId(), sysUserBindRolesReq.getRoleIds());
        return ApiResponseUtil.success(true);
    }

    @Operation(summary = "获取当前用户授权菜单")
    @GetMapping("allMenus")
    public ApiResponse<List<AdminUserMenuResp>> allMenus() {
        List<AdminUserMenuResp> adminUserMenuResps = adminUserService.listAdminUserMenus(StpUtil.getLoginIdAsLong());
        return ApiResponseUtil.success(adminUserMenuResps);
    }

    @Operation(summary = "退出登录")
    @OperationLog(moduleName = "管理员管理", eventName = "退出登录")
    @PostMapping("logout")
    public ApiResponse<Boolean> logout() {
        StpUtil.logout(StpUtil.getLoginIdAsLong());
        return ApiResponseUtil.success(true);
    }
}
